import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author Stringzhua
 * @Date 2024/10/31 10:32
 * description:
 */
public class ReentrantLockDemo02 {
    public static void main(String[] args) {
        TicketPool ticketPool = new TicketPool(30);

        new Thread(ticketPool, "窗口1").start();
        new Thread(ticketPool, "窗口2").start();
        new Thread(ticketPool, "窗口3").start();
    }
}

class TicketPool implements Runnable {
    //当前剩余门票数
    private int ticket;
    //锁
    private ReentrantLock lock;

    private Condition condition;

    public TicketPool(int ticket) {
        this.ticket = ticket;
        this.lock = new ReentrantLock();
        this.condition = lock.newCondition();
    }

    public int getTicket() {
        return ticket;
    }

    public void setTicket(int ticket) {
        this.ticket = ticket;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "开始卖票");
//        不同的售票窗口[线程],使用相同的当前对象(公共票池)
        final ReentrantLock lock = this.lock;

        //加锁
        lock.lock();
        try {
            while (true) {
                if (ticket <= 0) {
                    System.out.println(Thread.currentThread().getName() + "没票啦");
                    return;
                } else {
                    System.out.println(Thread.currentThread().getName() + "卖出了一张票,剩余:" + --ticket + "张门票");
                    //sleep()执行期间(休眠期间),持有当前锁的线程,不会释放锁[单个窗口卖30张票]
                    //Thread.sleep(1000);

                    //wait()执行期间(等待期间),持有当前锁的线程,会释放锁[多个窗口卖30张票]
                    try {
                        this.condition.await(1, TimeUnit.SECONDS);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } finally {
            lock.unlock();
        }
    }
}